/*
 * Copyright (C) 2008 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/** @defgroup time Time
 * @ingroup libc
 */

#ifndef _TIME_H_
#define _TIME_H_

#include <sys/cdefs.h>
#include <sys/time.h>
#include <xlocale.h>

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */


#define CLOCKS_PER_SEC 1000000

extern char* tzname[] __LIBC_ABI_PUBLIC__;
extern int daylight __LIBC_ABI_PUBLIC__;
extern long int timezone __LIBC_ABI_PUBLIC__;

struct sigevent;

struct tm {
  int tm_sec;
  int tm_min;
  int tm_hour;
  int tm_mday;
  int tm_mon;
  int tm_year;
  int tm_wday;
  int tm_yday;
  int tm_isdst;
  long int tm_gmtoff;
  const char* tm_zone;
};

#define TM_ZONE tm_zone

/**
* @ingroup  time
* @par Description:
* This function gets the value of time in seconds since the Epoch(1970-01-01 00:00:00 UTC).
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #time_t On success, this function shall return the value of time in seconds since the Epoch.
* the argument points to an area where the return value is also stored. If the argument is a null pointer,
* no value is stored.On failure, this function shall return (time_t)-1.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  asctime | clock | clock_getres | ctime | difftime | gettimeofday | gmtime | localtime |
* mktime | strftime | strptime | times | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern time_t time(time_t*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall cause the current thread to be suspended from execution
* until either the time interval specified by the first argument has elapsed.
*
* @attention
* <ul>
* <li>The second argument is unused.</li>
* <li>Tasks will not be awakened, if the requested time does not has elapsed </li>
* </ul>
*
* @retval #0  The function is executed successfully.
* @retval #-1 The function failed to execute, and corresponding error code is set.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  sleep
*
* @since Huawei LiteOS V100R001C00
*/
extern int nanosleep(const struct timespec*, struct timespec*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall convert the broken-down time in the structure pointed to by the argument into a string in the form:\n
* Sun Sep 16 01:03:52 1973\n\0.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #char* On success, this function shall return a pointer to the string. On failure, it shall return NULL.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  clock | ctime | difftime | gmtime | localtime |
* mktime | strftime | strptime | times | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern char* asctime(const struct tm*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall convert the broken-down time in the structure pointed to by first argument into a string.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #char* On success, this function shall return a pointer to a character string containing the date and time.
* This string is pointed to by the second argument. On failure, it shall return NULL.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  clock | ctime | difftime | gmtime | localtime |
* mktime | strftime | strptime | times | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern char* asctime_r(const struct tm*, char*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall compute the difference between two calendar times (as returned by time()).
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #double This function return the difference expressed in seconds as a type double.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  clock | ctime | asctime | gmtime | localtime |
* mktime | strftime | strptime | times | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern double difftime(time_t, time_t) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall convert the broken-down time, expressed as local time, in the structure pointed
* to by the argument,into a time since the Epoch value with the same encoding as that of the values
* returned by time(). The original values of the tm_wday and tm_yday components of the structure shall
* be ignored, and the original values of the other components shall not be restricted to the ranges
* described in <time.h>.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #time_t On success, shall return the specified time since the Epoch encoded as a value of type time_t.
* On failure, If the time since the Epoch cannot be represented, the function shall return the value (time_t)-1.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  asctime | clock | ctime | difftime | gmtime | localtime | strftime | strptime | time | tzset | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern time_t mktime(struct tm*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall convert the time in seconds since the Epoch pointed to by the argument
* into a broken-down time, expressed as a local time.
*
* @attention
* <ul>
* <li>Failure compared with standard, the error code is not seted.</li>
* </ul>
*
* @retval
* "struct tm*" On success, the function shall return a pointer to the broken-down time structure.
* On failure, this shall return a null pointer.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  asctime | clock | ctime | difftime | gmtime | mktime | strftime | strptime | time | tzset | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern struct tm* localtime(const time_t*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall convert the time in seconds since the Epoch pointed to by timer into
* a broken-down time stored in the structure to which the second argument points.
*
* @attention
* <ul>
* <li>Failure compared with standard, the error code is not seted. </li>
* </ul>
*
* @retval
* "struct tm*" On success, the function shall return a pointer to the structure pointed to by the second argument.
* On failure, this shall return a null pointer.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  asctime | clock | ctime | difftime | gmtime | mktime | strftime | strptime | time | tzset | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern struct tm* localtime_r(const time_t*, struct tm*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function convert the time in seconds since the Epoch pointed to by the argument into
* a broken-down time, expressed as Coordinated Universal Time (UTC).
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* "struct tm*" On success, this function returns a pointer to a struct tm.
* On failure, it shall return a null pointer.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  asctime | clock | ctime | difftime | localtime | mktime | strftime | strptime | time | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern struct tm* gmtime(const time_t*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function convert the time in seconds since the Epoch pointed to by the first argument into
* a broken-down time expressed as Coordinated Universal Time (UTC). The broken-down time is stored
* in the structure referred to by the second argument.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* "struct tm*" On success, this function returns the address of the structure pointed to by the second argument.
* On failure, it shall return a null pointer.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  asctime | clock | ctime | difftime | localtime | mktime | strftime | strptime | time | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern struct tm* gmtime_r(const time_t*, struct tm*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function converts the character string pointed to by the first argument to values which are stored in
* the tm structure pointed to by the third argument, using the format specified by the second argument.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #char* On success, this function returns a pointer to the character following the last character parsed.
* On failure, a null pointer shall be returned.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  fprintf | fscanf | strftime | time
*
* @since Huawei LiteOS V100R001C00
*/
extern char* strptime(const char*, const char*, struct tm*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function formats the broken-down time tm according to the format specification format and places the result in the character
* array s of size the second.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #size_t Provided  that  the  result  string, including the terminating null byte, does not exceed max bytes,
* it returns the number of bytes (excluding the terminating null byte) placed in the array s.
* If the length of the result string  (including  the  terminating  null  byte) would exceed max bytes,
* then it returns 0, and the contents of the array are undefined.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  asctime | clock | clock_getres | ctime | difftime | gettimeofday | gmtime | localtime |
* mktime | strptime | times | utime | tzset
*
* @since Huawei LiteOS V100R001C00
*/
extern size_t strftime(char *s, size_t max, const char *format, const struct tm *tm) __LIBC_ABI_PUBLIC__;
extern size_t strftime_l(char *, size_t, const char *, const struct tm *, locale_t) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall convert the time pointed to by the first argument, representing time in seconds since the Epoch,
* to local time in the form of a string.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #char* The function returns the pointer returned by asctime() with that broken-down time as an argument.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  asctime | clock | difftime | gmtime | localtime | mktime | strftime | strptime | time | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern char* ctime(const time_t*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall convert the calendar time pointed to by the first argument to local time in
* exactly the same form as ctime() and put the string into the array pointed to by the second argument
* (which shall be at least 26 bytes in size).
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #char* On success, the function returns a pointer to the string pointed to by second argument.
* On failure, a null pointer shall be returned.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  asctime | clock | difftime | gmtime | localtime | mktime | strftime | strptime | time | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern char* ctime_r(const time_t*, char*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function uses the value of the environment variable TZ to set time conversion information used
* by ctime, localtime, mktime, and strftime. If TZ is absent from the environment, implementation-defined default
* timezone information shall be used..
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* None
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  ctime | localtime | mktime | strftime
*
* @since Huawei LiteOS V100R001C00
*/
extern void tzset(void) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function gets the current time as an integer number of microseconds.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #clock_t This function returns the current time as an integer number of microseconds.
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  asctime | clock_getres | ctime | difftime | gmtime | localtime | mktime | strftime |
* strptime | time | times | utime
*
* @since Huawei LiteOS V100R001C00
*/
extern clock_t clock(void) __LIBC_ABI_PUBLIC__;

extern int clock_getcpuclockid(pid_t, clockid_t*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function finds  the  resolution  (precision) of the specified clock, and, if the second argument is non-NULL, stores it in the
* struct timespec pointed to by the second argument.
*
* @attention
* <ul>
* <li>The first argument of value only supports CLOCK_REALTIME.</li>
* </ul>
*
* @retval #0  The function is executed successfully.
* @retval #-1 The function failed to execute, and corresponding error code is set.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  gettimeofday | settimeofday | time | adjtime | ctime
*
* @since Huawei LiteOS V100R001C00
*/
extern int clock_getres(clockid_t, struct timespec*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function retrieves the time of the specified clock.
*
* @attention
* <ul>
* <li>The first argument of value only supports CLOCK_REALTIME.</li>
* </ul>
*
* @retval #0  The function is executed successfully.
* @retval #-1 The function failed to execute, and corresponding error code is set.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  gettimeofday | settimeofday | time | adjtime | ctime
*
* @since Huawei LiteOS V100R001C00
*/
extern int clock_gettime(clockid_t, struct timespec*) __LIBC_ABI_PUBLIC__;
extern int clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function sets the time of the specified clock clk_id.
*
* @attention
* <ul>
* <li>The first argument of value only supports CLOCK_REALTIME.</li>
* </ul>
*
* @retval #0  The function is executed successfully.
* @retval #-1 The function failed to execute, and corresponding error code is set.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  gettimeofday | settimeofday | time | adjtime | ctime
*
* @since Huawei LiteOS V100R001C00
*/
extern int clock_settime(clockid_t, const struct timespec*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function creates a per-process timer using the specified clock, as the timing base.
* The function shall return, in the location referenced by the third argument, a timer ID
* of type timer_t used to identify the timer in timer requests.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval #0  The function is executed successfully.
* @retval #-1 The function failed to execute, and corresponding error code is set.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* <li><b>EAGAIN</b>: Duplicate creation.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  clock_getres | timer_delete | timer_getoverrun
*
* @since Huawei LiteOS V100R001C00
*/
extern int timer_create(int, struct sigevent*, timer_t*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function deletes the specified timer,previously created by the timer_create() function.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval #0  The function is executed successfully.
* @retval #-1 The function failed to execute, and corresponding error code is set.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  timer_create
*
* @since Huawei LiteOS V100R001C00
*/
extern int timer_delete(timer_t) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function set the time until the next expiration of the timer specified by timerid from
* the it_value member of the third argument and arm the timer if the it_value member of value is non-zero.
*
* @attention
* <ul>
* <li>the second parameter is unused</li>
* </ul>
*
* @retval #0  The function is executed successfully.
* @retval #-1 The function failed to execute, and corresponding error code is set.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  clock_getres | timer_create
*
* @since Huawei LiteOS V100R001C00
*/
extern int timer_settime(timer_t, int, const struct itimerspec*, struct itimerspec*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall store the amount of time until the specified timer,
* expires and the reload value of the timer into the space pointed to by the second argument.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval #0  The function is executed successfully.
* @retval #-1 The function failed to execute, and corresponding error code is set.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  clock_getres | timer_create
*
* @since Huawei LiteOS V100R001C00
*/
extern int timer_gettime(timer_t, struct itimerspec*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function shall get the timer expiration overrun count for the specified timer.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @retval
* #int On success, this function returns the timer expiration overrun count as explained above.
* On failure, -1 is returned.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  clock_getres | timer_create
*
* @since Huawei LiteOS V100R001C00
*/
extern int timer_getoverrun(timer_t) __LIBC_ABI_PUBLIC__;

/* Non-standard extensions that are in the BSDs and glibc. */
extern time_t timelocal(struct tm*) __LIBC_ABI_PUBLIC__;
extern time_t timegm(struct tm*) __LIBC_ABI_PUBLIC__;

/**
* @ingroup  time
* @par Description:
* This function  sets  the  system's  idea  of  the  time  and date.  The time, pointed to by t, is measured in seconds since the Epoch.
*
* @attention
* <ul>
* <li>There are no restrictions on the use of superusers.</li>
* </ul>
*
* @retval #0  The function is executed successfully.
* @retval #-1 The function failed to execute, and corresponding error code is set.
*
* @par Errors
* <ul>
* <li><b>EINVAL</b>: An invalid input.</li>
* </ul>
*
* @par Dependency:
* <ul><li>time.h</li></ul>
*
* @see  settimeofday
*
* @since Huawei LiteOS V100R001C00
*/
extern int stime(time_t *t) __LIBC_ABI_PUBLIC__;

#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */

#endif /* _TIME_H_ */
